﻿''' <summary>
''' Marker interface to denote anything as being a projection over the given aggregate identifier
''' </summary>
''' <remarks>
''' The type-safety is to ensure the projection only operates on events of one kind
''' </remarks>
Public Interface IProjection(Of TAggregate As IAggregationIdentifier, TAggregateKey)
    Inherits IProjection

    ''' <summary>
    ''' Process the event stream for the uniquely identified aggregate 
    ''' </summary>
    ''' <param name="stream">
    ''' The set of events for the given uniquely identified aggregate
    ''' </param>
    ''' <param name="priorSnapshot">
    ''' The starting point for processing the events stream.  If this is not specified then always
    ''' start from the very begining of the event stream
    ''' </param>
    Overloads Sub ProcessEventStream(ByVal stream As IEventStream(Of TAggregate, TAggregateKey),
                           Optional ByVal priorSnapshot As IProjectionSnapshot(Of TAggregate, TAggregateKey) = Nothing
                           )


    ''' <summary>
    ''' Take a snapshot of the projection for where we are currently
    ''' </summary>
    Overloads Function TakeSnapshot() As IProjectionSnapshot(Of TAggregate, TAggregateKey)

End Interface

''' <summary>
''' Marker interface to denote anything as being a projection
''' </summary>
Public Interface IProjection


    ''' <summary>
    ''' Process the event stream for the uniquely identified aggregate 
    ''' </summary>
    ''' <param name="stream">
    ''' The set of events for the given uniquely identified aggregate
    ''' </param>
    ''' <param name="priorSnapshot">
    ''' The starting point for processing the events stream.  If this is not specified then always
    ''' start from the very begining of the event stream
    ''' </param>
    Sub ProcessEventStream(Of TAggregate As IAggregationIdentifier, TAggregateKey)(ByVal stream As IEventStream(Of TAggregate, TAggregateKey),
                           Optional ByVal priorSnapshot As IProjectionSnapshot(Of TAggregate, TAggregateKey) = Nothing
                           )

    ''' <summary>
    ''' Take a snapshot of the projection as at the current state 
    ''' </summary>
    ''' <typeparam name="TAggregate">
    ''' The identifier of aggregate over which the projection is running
    ''' </typeparam>
    ''' <typeparam name="TAggregateKey">
    ''' The type of the key that uniquely identifies an instance of that aggregate
    ''' </typeparam>
    ''' <returns>
    ''' A projection snapshot that can be used to persist the state of the aggregate
    ''' </returns>
    Function TakeSnapshot(Of TAggregate As IAggregationIdentifier, TAggregateKey)() As IProjectionSnapshot(Of TAggregate, TAggregateKey)

End Interface